#include <map>
#include <string>
#include <vector>
#include <iostream>
using namespace std;
#include <sys/select.h>
#include "sys/thread.h"
#include "net/socket.h"
#include "mem/small_buffer.h"
using namespace tdl;

#ifdef OS_MAC
tdl::host_addr ha = "127.0.0.1:9527";
#else
tdl::host_addr ha = "192.168.1.100:9527";
#endif

void do_server()
{
	fd_set rfds, wfds;
	tdl::small_buffer<1024> sb;
	
	try {
		tdl::udp_socket pus = tdl::udp_socket::create();
		pus.bind(ha);

		while(1)
		{
			FD_ZERO(&rfds);
			FD_ZERO(&wfds);
			FD_SET(pus.get_fd(), &rfds);
			
			int r = ::select(pus.get_fd() + 1, &rfds, &wfds, NULL, NULL);
			if(r < 0)
			{
				cerr << strerror(errno) << endl;
				return;
			}
			if(r > 0 && FD_ISSET(pus.get_fd(), &rfds))
			{
				host_addr cli_ha;
				memset(sb.ptr, 0, sb.size);
				sb.len = pus.recvfrom(sb.ptr, sb.size, cli_ha);
				cout << "got from " << cli_ha << ": " << string(sb.ptr, sb.len) << endl;
			}
		}
	} catch(socket_ex& e) {
		cerr << "server: " << e.what_hell() << endl;
		return;
	}
}

void do_client()
{
	string s = "hello tommy";
#ifdef OS_MAC
	host_addr cli_ha = "127.0.0.1:9000";
#else
	host_addr cli_ha = "192.168.1.100:9000";
#endif

	try {
		tdl::udp_socket us = tdl::udp_socket::create();
		us.bind(cli_ha);
		while(1)
		{
			us.sendto(s.c_str(), s.length(), ha);
			sleep(1);
		}
	} catch(socket_ex& e) {
		cerr << "client: " << e.what_hell() << endl;
		return;
	}
}

//////////////////////
int main(int argc, char* argv[])
{
	thread s(make_fun_exec(&do_server), false);
	thread c(make_fun_exec(&do_client), false);
	
	s.run();
	c.run();
	
	s.wait();
	c.wait();
	
	return 0;
}
